
import { gsap } from 'gsap';
import * as THREE from 'three';
export default function modifyCityMaterail(mesh) {
    mesh.material.onBeforeCompile = (shader, render) => {
        shader.fragmentShader = shader.fragmentShader.replace(
            '#include <dithering_fragment>',
            `#include <dithering_fragment>
            //#end#`)
        addGradColor(shader, mesh)
        addSpared(shader)
        addLine(shader)
        addLineY(shader)
    }
}

export function addGradColor(shader, mesh) {
    // 通过以下这个方法获得整个建模物体的最大值和最小值,要计算之后才拿得到
    mesh.geometry.computeBoundingBox()
    let { min, max } = mesh.geometry.boundingBox
    let uHeight = max.y - min.y
    // 获得高度差通过uniform传进来
    shader.uniforms.uHeight = {
        value: uHeight
    }
    // 设置想要的顶点颜色
    shader.uniforms.uTopColor = {
        value: new THREE.Color('#aaaeff')
    }
    // 先把顶点着色器里面的顶点位置拿出来
    shader.vertexShader = shader.vertexShader.replace(
        '#include <common>',
        `#include <common>
    varying vec3 vPosition;`
    )
    shader.vertexShader = shader.vertexShader.replace(
        '#include <begin_vertex>',
        `#include <begin_vertex>
    vPosition = position;`
    )
    // 然后片段着色器先声明顶点颜色，落差高度和顶点位置
    shader.fragmentShader = shader.fragmentShader.replace(
        '#include <common>',
        `#include <common>
    varying vec3 vPosition;
    uniform vec3 uTopColor;
    uniform float uHeight;`
    )
    // 逻辑开始，在片段着色器最后一行添加
    shader.fragmentShader = shader.fragmentShader.replace(
        '//#end#',
        `
    // 拿到原本的颜色
    vec4 distGradColor = gl_FragColor;
    // 设置混合百分比
    float gradMix = (vPosition.y + uHeight / 2.0) / uHeight;
    // 计算出混合颜色
    vec3 gradMixColor = mix(distGradColor.xyz,uTopColor,gradMix);
    gl_FragColor = vec4(gradMixColor,1);
    //#end#
    `
    )
}

export function addSpared(shader) {
    // 设置扩散的中心点，因为是一个平面整体建模，所以就是一个二维的中心点
    shader.uniforms.uSpreadCenter = { value: new THREE.Vector2(0, 0) }
    // 扩散的时间
    shader.uniforms.uSpreadTime = { value: 0 }
    // 设置条带宽度
    shader.uniforms.uSpreadWidth = { value: 40 }
    // 先声明变量
    shader.fragmentShader = shader.fragmentShader.replace(
        '#include <common>',
        `#include <common>
    uniform vec2 uSpreadCenter;
    uniform float uSpreadTime;
    uniform float uSpreadWidth;
    `
    )
    shader.fragmentShader = shader.fragmentShader.replace(
        '//#end#',
        `
        // 设置顶点到原点的距离，也就是半径这里注意，之前在前面那个函数已经拿到了uv顶点所以这里可以直接用
        float spreadRadius = distance(vPosition.xz,uSpreadCenter);
        // 这里设置结合图理解，就是-x的平方是一个弯弯向下的放到平面上来就是一圈一圈的，3D类似是立在我面前的样子，配合时间实现动起来，后面加宽度是因为右上的图本来是在0以下，加上一个合理范围才会在0以上，才会显示出来
        float spreadIndex = -(spreadRadius - uSpreadTime) * (spreadRadius - uSpreadTime) + uSpreadWidth;
        // 设置混合颜色本来的颜色和白色，百分比由上面算出来的扩散范围是一个0-1的值，除以宽度
        if(spreadIndex > 0.0) {
            gl_FragColor = mix(gl_FragColor,vec4(1,1,1,1),spreadIndex / uSpreadWidth);
        }
        //#end#
    `
    )
    gsap.to(shader.uniforms.uSpreadTime, {
        value: 800,
        duration: 2,
        ease: 'none',
        repeat: -1
    })
}
export function addLine(shader) {
    // 扩散的时间
    shader.uniforms.uLineTime = { value: -500 }
    // 设置条带宽度
    shader.uniforms.uLineWidth = { value: 40 }
    // 先声明变量
    shader.fragmentShader = shader.fragmentShader.replace(
        '#include <common>',
        `#include <common>
    uniform float uLineTime;
    uniform float uLineWidth;
    `
    )
    shader.fragmentShader = shader.fragmentShader.replace(
        '//#end#',
        `
        float LineIndex = -(vPosition.x + vPosition.z - uLineTime) * (vPosition.x + vPosition.z - uLineTime) + uLineWidth;
        // 设置混合颜色本来的颜色和白色，百分比由上面算出来的扩散范围是一个0-1的值，除以宽度
        if(LineIndex > 0.0) {
            gl_FragColor = mix(gl_FragColor,vec4(1,1,1,1),LineIndex / uLineWidth);
        }
        //#end#
    `
    )
    gsap.to(shader.uniforms.uLineTime, {
        value: 500,
        duration: 5,
        ease: 'none',
        repeat: -1
    })
}
export function addLineY(shader) {
    // 扩散的时间
    shader.uniforms.uLineYTime = { value: 0 }
    // 设置条带宽度
    shader.uniforms.uLineYWidth = { value: 40 }
    // 先声明变量
    shader.fragmentShader = shader.fragmentShader.replace(
        '#include <common>',
        `#include <common>
    uniform float uLineYTime;
    uniform float uLineYWidth;
    `
    )
    shader.fragmentShader = shader.fragmentShader.replace(
        '//#end#',
        `
        float LineYIndex = -(vPosition.y  - uLineYTime) * (vPosition.y - uLineYTime) + uLineYWidth;
        // 设置混合颜色本来的颜色和白色，百分比由上面算出来的扩散范围是一个0-1的值，除以宽度
        if(LineYIndex > 0.0) {
            gl_FragColor = mix(gl_FragColor,vec4(1,1,1,1),LineYIndex / uLineYWidth);
        }
        //#end#
    `
    )
    gsap.to(shader.uniforms.uLineYTime, {
        value: 500,
        duration: 2,
        ease: 'none',
        repeat: -1
    })
}